<?php

    include_once "WXBizMsgCrypt.php";
    class QiyeWechat {
        public $m_sToken;
        public $m_sEncodingAesKey;
        public $m_sCorpid;

        /**
         * 构造函数
         * @param $token string 公众平台上，开发者设置的token
         * @param $encodingAesKey string 公众平台上，开发者设置的EncodingAESKey
         * @param $Corpid string 公众平台的Corpid
         */
        public function __construct($token, $encodingAesKey, $Corpid)
        {
            header("Content-Type:text/html; charset=utf-8");
            $this->Token = $token;
            $this->EncodingAesKey = $encodingAesKey;
            $this->Corpid = $Corpid;
            //开启session
            if(!isset($_SESSION)){
                session_start();
            }
        }
        /*
         *
         * 错误检查方法，企业微信后台点击保存，如果失败，原因可能有多种，需一步步排查，可以直接用这个，然后一步步调试，该错误无法直观显示，用缓存或加入数据库的方法，查看错误
         *
         *
         * */

        public function index()
        {
            /*
          ------------使用示例一：验证回调URL---------------
          *企业开启回调模式时，企业号会向验证url发送一个get请求
          假设点击验证时，企业收到类似请求：
          * GET /cgi-bin/wxpush?msg_signature=5c45ff5e21c57e6ad56bac8758b79b1d9ac89fd3&timestamp=1409659589&nonce=263014780&echostr=P9nAzCzyDtyTWESHep1vC5X9xho%2FqYX3Zpb4yKa9SKld1DsH3Iyt3tP3zNdtp%2B4RPcs8TgAE7OaBO%2BFZXvnaqQ%3D%3D
          * HTTP/1.1 Host: qy.weixin.qq.com

          接收到该请求时，企业应
          1.解析出Get请求的参数，包括消息体签名(msg_signature)，时间戳(timestamp)，随机数字串(nonce)以及公众平台推送过来的随机加密字符串(echostr),
          这一步注意作URL解码。
          2.验证消息体签名的正确性
          3. 解密出echostr原文，将原文当作Get请求的response，返回给公众平台
          第2，3步可以用公众平台提供的库函数VerifyURL来实现。

          */

            //此处接收参数
            $sVerifyMsgSig = urldecode($_GET['msg_signature']);

            $sVerifyTimeStamp = urldecode($_GET['timestamp']);

            $sVerifyNonce = urldecode($_GET['nonce']);

            $sVerifyEchoStr = $_GET['echostr'];

            // 需要返回的明文
            header('content-type:text');
            $sEchoStr = "";

            $wxcpt = new WXBizMsgCrypt($this->Token, $this->EncodingAesKey, $this->Corpid);
            $errCode = $wxcpt->VerifyURL($sVerifyMsgSig, $sVerifyTimeStamp, $sVerifyNonce, $sVerifyEchoStr, $sEchoStr);
            if ($errCode == 0) { //验证成功!
                echo $sEchoStr;
                exit;
            } else { //验证失败，返回v错误，可以存session或者直接加入数据库查询错误！
                print("ERR: " . $errCode . "\n\n");
            }

            //判断企业微后台是否推送suite_ticket到该url，post形式
            if($_SERVER['REQUEST_METHOD'] === 'POST' ){
                //必须通过输入流方式获取post数据,，接收到的$sReqData 为xml格式，需转换成对象或其他格式
                $sReqData = file_get_contents("php://input");
                $xml =  simplexml_load_string($sReqData,'SimpleXMLElement', LIBXML_NOCDATA); // yii xml格式转成对象
                $ToUserName = $xml->ToUserName; //获取到的suite_id
                if($this->suite_id == $ToUserName){ //证明是企业微信后台推送
                    $wxcpt = new WXBizMsgCrypt($this->token, $this->encodingAesKey, $ToUserName);
                    $sMsg     = '';  // 解析之后的明文
                    $err_code = $wxcpt->DecryptMsg($sVerifyMsgSig, $sVerifyTimeStamp, $sVerifyNonce, $sReqData, $sMsg);//var_dump($get,$err_code,$sMsg);//exit;\
                    $xmls = simplexml_load_string($sMsg,'SimpleXMLElement', LIBXML_NOCDATA); // yii xml格式转成对象
                    if($err_code == 0){
                        switch ($xmls->InfoType) {
                            case 'suite_ticket'://推送suite_ticket协议每十分钟微信推送一次
                                $suite_ticket = $xml->SuiteTicket;
                                if (!empty($suite_ticket)) {
                                    //1.缓存redis suite_ticket ,过期时间 30分钟，每10分钟刷新一次，600s
                                    $_SESSION['suite_ticket'] = $suite_ticket;
                                    echo 'success';  // 返回企业微信消息 success
                                }
                                else {
                                    //错误信息
                                    echo 200;
                                }

                                break;

                            case 'cancel_auth'://取消授权的通知 -- 特指套件取消授权
                                $auth_corp_id = $xml->getElementsByTagName('AuthCorpId')->item(0)->nodeValue;//普通企业的corpid
                                //自己的业务需求
                                break;

                        }
                    }

                }


            }


        }



}


